/*
ATTENTION:
	PLL
	40M > refclk/L1_div_ref >20M
	3.2G > refclk/ L1_div_ref*L1_loopc > 1.2G
	node_clock = refclk/L1_div_ref*L1_loopc/L1_divout/L2_divout
*/
#define SOFT_CLKSEL

#ifndef DDR_FREQ
/* MEM @ 400Mhz */
#define DDR_FREQ   400
#endif

#ifdef SOFT_CLKSEL
#define DDR_REFC   4
#define DDR_DIV    1
#define DDR_DIV_L2 4
#define DDR_LOOPC  (DDR_FREQ*DDR_REFC*DDR_DIV*DDR_DIV_L2/REF_FREQ)

#ifndef CORE_FREQ
/* CPU @ 800Mhz */
#define CORE_FREQ   800
#endif

#define L1_REFC     4
#define L1_DIV      1
#if CORE_FREQ >= 600
#define L2_DIV      2
#else
#define L2_DIV      4
#endif
#define L1_LOOPC  (CORE_FREQ*L1_DIV*L2_DIV*L1_REFC/REF_FREQ)

/* GPU @ 400Mhz */
#define HDA_FREQ	24
#define GPU_DIV_L2	7
#define HDA_DIV_L2	(DDR_FREQ*DDR_DIV_L2/HDA_FREQ)

/* DC @ 200Mhz */
/* GMAC @ 125Mhz */
#define DC_LOOPC    80
#define DC_REFC     4
#define DC_DIV      1
#define DC_DIV_L2   8
#define GMAC_DIV    16

#define PIX0_LOOPC	109
#define PIX0_REFC	5
#define PIX0_DIV	1
#define PIX0_DIV_L2	20

#define PIX1_LOOPC	109
#define PIX1_REFC	5
#define PIX1_DIV	1
#define PIX1_DIV_L2	20
#define BYPASS_CORE 0x0
#define BYPASS_NODE 0x0
#define BYPASS_L1   0x0

#define PLL_SEL0	(0x1)
#define PLL_SEL1	(0x1 << 1)
#define PLL_SEL2	(0x1 << 2)

#define PLL_L1_PD_PLL		(0x1 << 19)
#define PLL_L1_LOCKED 		(0x1 << 16)
#define PLL_L1_ENA			(0x1 << 2)

#define PLL_MEM_ENA			(0x1 << 2)
#define PLL_MEM_LOCKED 		(0x1 << 16)

	// TTYDBG ("Soft CLK SEL adjust begin\r\n")
	li.d	t0, LS_NODE_PLL_L
	li.d	t1, PLL_L1_PD_PLL 	//power down pll L1 first
	st.d	t1, t0, 0
	li.d	t1, (L1_LOOPC << 32) | (L1_DIV << 42) | (L1_REFC << 26) | (0x3 << 10) | (0x1 << 7)
	li.d	t2, L2_DIV
	st.d	t1, t0, 0
	st.d	t2, t0, 8
	ori		t1, t1, PLL_L1_ENA
	st.d    t1, t0, 0

11:
	ld.d	a0, t0, 0
	li.d	a1, PLL_L1_LOCKED
	and		a0, a1, a0
	beqz	a0, 11b //wait_locked_sys
	nop

	ld.d	a0, t0, 0
	ori     a0, a0, PLL_SEL0
	st.d    a0, t0, 0

	// TTYDBG ("\r\nMEM        :")
	li.d	t0, LS_DDR_PLL_L
	li.d	t1, PLL_L1_PD_PLL	//power down pll  first
	st.d	t1, t0, 0
	li.d    t1, (DDR_DIV << 42) | (DDR_REFC << 26) | (DDR_LOOPC << 32) | (0x3 << 10) | (0x1 << 7)
	li.d	t2, (GPU_DIV_L2 << 22) | (DDR_DIV_L2) | (HDA_DIV_L2 << 44)
	st.d	t1, t0, 0
	st.d	t2, t0, 0x8
	ori		t1, t1, PLL_L1_ENA
	st.d    t1, t0, 0

21:
	ld.w	a0, t0, 0
	li.w    a1, PLL_MEM_LOCKED
	and     a0, a0, a1
	beqz    a0, 21b //wait_locked_ddr
	nop

	ld.w	a0, t0, 0
	ori		a0, a0, PLL_SEL0 | PLL_SEL1
	st.w	a0, t0, 0

	// TTYDBG ("\r\nDC        :")
	li.d	t0, LS_DC_PLL_L
	li.w	t1, PLL_L1_PD_PLL	//power down pll  first
	st.d	t1, t0, 0
	li.d    t1, (DC_DIV << 42) | (DC_REFC << 26) | (DC_LOOPC << 32) | (0x3 << 10) | (0x1 << 7)
	li.d	t2, (GMAC_DIV << 22) | (DC_DIV_L2)
	st.d	t1, t0, 0
	st.d	t2, t0, 0x8
	ori		t1, t1, PLL_L1_ENA
	st.d    t1, t0, 0

21:
	ld.w	a0, t0, 0
	li.w    a1, PLL_MEM_LOCKED
	and     a0, a0, a1
	beqz    a0, 21b //wait_locked_ddr
	nop

	ld.w	a0, t0, 0
	ori     a0, a0, PLL_SEL0 | PLL_SEL1
	st.w	a0, t0, 0

	// TTYDBG ("\r\nPIX0        :")
	li.d	t0, LS_PIX0_PLL_L		//pll_pix0
	li.w	t1, PLL_L1_PD_PLL	//power down pll  first
	st.d	t1, t0, 0
	li.d    t1, (PIX0_DIV << 42) | (PIX0_REFC << 26) | (PIX0_LOOPC << 32) | (0x3 << 10) | (0x1 << 7)
	li.d	t2, PIX0_DIV_L2
	st.d	t1, t0, 0
	st.d	t2, t0, 0x8
	ori	t1, t1, PLL_L1_ENA
	st.d    t1, t0, 0

21:
	ld.w    a0, t0, 0
	li.w    a1, PLL_MEM_LOCKED
	and     a0, a0, a1
	beqz    a0, 21b
	nop

	ld.w    a0, t0, 0
	ori     a0, a0, PLL_SEL0
	st.w    a0, t0, 0

	// TTYDBG ("\r\nPIX1        :")
	li.d	t0, LS_PIX1_PLL_L		//pll_pix1
	li.w	t1, PLL_L1_PD_PLL	//power down pll  first
	st.d	t1, t0, 0
	li.d    t1, (PIX1_DIV << 42) | (PIX1_REFC << 26) | (PIX1_LOOPC << 32) | (0x3 << 10) | (0x1 << 7)
	li.d	t2, PIX1_DIV_L2
	st.d	t1, t0, 0
	st.d	t2, t0, 0x8
	ori		t1, t1, PLL_L1_ENA
	st.d    t1, t0, 0

21:
	ld.w    a0, t0, 0
	li.w    a1, PLL_MEM_LOCKED
	and     a0, a0, a1
	beqz    a0, 21b
	nop

	ld.w    a0, t0, 0
	ori     a0, a0, PLL_SEL0 | PLL_SEL1
	st.w    a0, t0, 0
#endif
